﻿<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
  
  <head>
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-39155502-5"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
  
      gtag('config', 'UA-39155502-5');
    </script>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Fuzzy Text Search | MongoDB.Entities </title>
    <meta name="viewport" content="width=device-width">
    <meta name="title" content="Fuzzy Text Search | MongoDB.Entities ">
    <meta name="generator" content="docfx 2.58.4.0">
    <meta name="description" content="A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management.">
    <link rel="shortcut icon" href="../images/favicon.ico">
    <link rel="stylesheet" href="../styles/docfx.vendor.css">
    <link rel="stylesheet" href="../styles/docfx.css">
    <link rel="stylesheet" href="../styles/main.css">
    <meta property="docfx:navrel" content="../toc.html">
    <meta property="docfx:tocrel" content="toc.html">
    
    <meta property="docfx:rel" content="../">
    <meta property="docfx:newtab" content="true">
    <meta property="og:title" content="MongoDB.Entities">
    <meta property="og:site_name" content="MongoDB.Entities">
    <meta property="og:url" content="https://mongodb-entities.com">
    <meta property="og:description" content="A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management,">
    <meta property="og:type" content="website">
    <meta property="og:image" content="https://mongodb-entities.com/images/social-square.png">  
  </head>
  <body data-spy="scroll" data-target="#affix" data-offset="120">
    <div id="wrapper">
      <header>
        
        <nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
          <div class="container">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              
              <a class="navbar-brand" href="../index.html">
                <img id="logo" class="svg" src="../images/icon.png" alt="">
              </a>
            </div>
            <div class="collapse navbar-collapse" id="navbar">
              <form class="navbar-form navbar-right" role="search" id="search">
                <div class="form-group">
                  <input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
                </div>
              </form>
            </div>
          </div>
        </nav>
        
        <div class="subnav navbar navbar-default">
          <div class="container hide-when-search" id="breadcrumb">
            <ul class="breadcrumb">
              <li></li>
            </ul>
          </div>
        </div>
      </header>
      <div class="container body-content">
        
        <div id="search-results">
          <div class="search-list">Search Results for <span></span></div>
          <div class="sr-items">
            <p><i class="glyphicon glyphicon-refresh index-loading"></i></p>
          </div>
          <ul id="pagination" data-first="First" data-prev="Previous" data-next="Next" data-last="Last"></ul>
        </div>
      </div>
      <div role="main" class="container body-content hide-when-search">
        
        <div class="sidenav hide-when-search">
          <a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
          <div class="sidetoggle collapse" id="sidetoggle">
            <div id="sidetoc"></div>
          </div>
        </div>
        <div class="article row grid-right">
          <div class="col-md-10">
            <article class="content wrap" id="_content" data-uid="">
<h1 id="fuzzy-text-search">Fuzzy Text Search</h1>

<p>fuzzy text matching is done using the <a href="https://en.wikipedia.org/wiki/Metaphone">double metaphone</a> algorythm. with it you can find non-exact matches that sounds similar to your search term.</p>
<p>fuzzy matching will only work on properties that are of the type <a class="xref" href="../api/MongoDB.Entities.FuzzyString.html">FuzzyString</a> which is supplied by this library. it also requires adding these properties to a text index.</p>
<p>here's how you'd typically get the fuzzy search to work:</p>
<h2 id="1-define-entity-class">1. Define entity class</h2>
<pre><code class="lang-csharp">public class Book : Entity
{
    public FuzzyString AuthorName { get; set; }
}
</code></pre>
<h2 id="2-create-text-index">2. Create text index</h2>
<pre><code class="lang-csharp">await DB.Index&lt;Book&gt;()
        .Key(b =&gt; b.AuthorName, KeyType.Text)
        .CreateAsync();
</code></pre>
<h2 id="3-store-the-entity">3. Store the entity</h2>
<pre><code class="lang-csharp">await new Book { AuthorName = &quot;Eckhart Tolle&quot; }.SaveAsync();
</code></pre>
<h2 id="4-do-a-fuzzy-search-on-the-index">4. Do a fuzzy search on the index</h2>
<pre><code class="lang-csharp">var results = await DB.Find&lt;Book&gt;()
                      .Match(Search.Fuzzy, &quot;ekard tole&quot;)
                      .ExecuteAsync();
</code></pre>
<p>that's all there's to it...</p>
<p>in case you need to start a flunt aggregation pipeline with fuzzy text matching, you can do it like so:</p>
<pre><code class="lang-csharp">DB.FluentTextSearch&lt;Book&gt;(Search.Fuzzy, &quot;ekard tole&quot;)
</code></pre>
<h1 id="how-it-works">How it works</h1>
<p>when you store text using <code>FuzzyString</code> class, the resulting mongodb document will look like this:</p>
<pre><code class="lang-java">{
  ...
  &quot;AuthorName&quot;: {
      &quot;Value&quot;: &quot;Eckhart Tolle&quot;,
      &quot;Hash&quot;: &quot;AKRT TL&quot;
  }
  ...
}
</code></pre>
<p>the text is stored in both the original form and also a hash consisting of double metaphone key codes for each word. when you perform a fuzzy search, your search term is converted to double metaphone key codes on the fly and matched against the stored hash to find results using standard mongodb full text functionality.</p>
<h1 id="sorting-fuzzy-results">Sorting Fuzzy Results:</h1>
<p>if you'd like to sort the results by relevence (closeness to the original search term) you can use the following utility method:</p>
<pre><code class="lang-csharp">var sortedResults = results.SortByRelevance(&quot;ekard tole&quot;, b =&gt; b.AuthorName);
</code></pre>
<p>this sorting is done client-side after the fuzzy search retrieves the entities from mongodb. what this extension method does is; it will compare your search term with the value of the property you specify as the second argument to see how close it is using <a href="https://en.wikipedia.org/wiki/Levenshtein_distance">levenshtein distance</a> algorythm. then it will return a new list with the closest matches at the top.</p>
<p>you can also exclude items from the resulting list that has a greater edit distance than a given value by specifiying the <code>maxDistance</code> optional parameter like so:</p>
<pre><code class="lang-csharp">var sortedResults = results.SortByRelevance(&quot;ekard tole&quot;, b =&gt; b.AuthorName, 10);
</code></pre>
<h1 id="performance-considerations">Performance considerations:</h1>
<p>by default, you are only allowed to store strings of up to 250 characters in length, which is roughly about 25 to 30 words max. if the you try to store strings larger than that, an exception will be thrown. this is to discourage abuse of this feature which would lead to performance degradation and wasted resources.</p>
<p>however, you have the option of changing the default limit at application startup by setting the following static property:</p>
<pre><code class="lang-csharp">FuzzyString.CharacterLimit = 500;
</code></pre>
</article>
          </div>
          
          <div class="hidden-sm col-md-2" role="complementary">
            <div class="sideaffix">
              <div class="contribution">
                <ul class="nav">
                </ul>
              </div>
              <nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
                <h5>In This Article</h5>
                <div></div>
              </nav>
            </div>
          </div>
        </div>
      </div>
      
      <footer>
        <div class="grad-bottom"></div>
        <div class="footer">
          <div class="container">
            <span class="pull-right">
              <a href="#top">Back to top</a>
            </span>
            Developed by <a href='https://github.com/dj-nitehawk'>Đĵ ΝιΓΞΗΛψΚ</a> and <a href='https://github.com/dj-nitehawk/MongoDB.Entities/graphs/contributors'>contributors</a> / Licensed under <a href='https://github.com/dj-nitehawk/MongoDB.Entities/blob/master/LICENSE'>MIT</a> / Website generated by <a href='https://dotnet.github.io/docfx/'>DocFX</a>
            
          </div>
        </div>
      </footer>
    </div>
    
    <script type="text/javascript" src="../styles/docfx.vendor.js"></script>
    <script type="text/javascript" src="../styles/docfx.js"></script>
    <script type="text/javascript" src="../styles/main.js"></script>
  </body>
</html>
